{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3小时Java入门"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 〇，编程环境"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "工程项目推荐使用IDEA.\n",
    "\n",
    "入门学习推荐使用Jupyter notebook.\n",
    "\n",
    "安装jupyter notebook的java插件 IJava 的方法如下:\n",
    "\n",
    "1,下载Java JDK >= 9.建议12\n",
    "\n",
    "2,下载ijava-1.3.0.zip,并解压。\n",
    "\n",
    "3,进入解压后目录，运行 python3 install.py --sys-prefix。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "详细参见： https://github.com/SpencerPark/IJava\n",
    "\n",
    "也可以在以下网页链接中直接尝试IJava：\n",
    "\n",
    "https://mybinder.org/v2/gh/SpencerPark/ijava-binder/master"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T23:56+0000",
     "start_time": "2019-09-15T23:56:14.774Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello World\n"
     ]
    }
   ],
   "source": [
    "//环境测试代码\n",
    "public class HelloWorld {\n",
    "    public static void main(String []args) {\n",
    "        System.out.println(\"Hello World\");\n",
    "    }\n",
    "}\n",
    "\n",
    "HelloWorld.main(new String[]{})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 一，算数运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T04:05+0000",
     "start_time": "2019-09-15T04:05:41.336Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "31"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//四则运算\n",
    "1+(100-20)/4+5*2 "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:42+0000",
     "start_time": "2019-09-15T03:42:37.355Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//求模运算\n",
    "5%2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T04:11+0000",
     "start_time": "2019-09-14T04:11:51.330Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "8.0"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//乘方运算\n",
    "Math.pow(2,3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:38+0000",
     "start_time": "2019-09-14T12:38:50.330Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//绝对值\n",
    "Math.abs(-2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:38+0000",
     "start_time": "2019-09-14T12:38:52.760Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1.5574077246549023"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//三角函数\n",
    "Math.tan(1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:38+0000",
     "start_time": "2019-09-14T12:38:55.330Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "4.605170185988092"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//对数函数\n",
    "Math.log(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:38+0000",
     "start_time": "2019-09-14T12:38:55.960Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "20.085536923187668"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//指数函数\n",
    "Math.exp(3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:11.778Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.11637436874314233"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//生成随机数\n",
    "Random r = new Random();\n",
    "r.nextInt(); // 2071575453,每次都不一样\n",
    "r.nextInt(10); // 5,生成一个[0,10)之间的int\n",
    "r.nextLong(); // 8811649292570369305,每次都不一样\n",
    "r.nextFloat(); // 0.54335...生成一个[0,1)之间的float\n",
    "r.nextDouble(); // 0.3716...生成一个[0,1)之间的double"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:38+0000",
     "start_time": "2019-09-14T12:38:56.654Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1038139898254934519337311789327024180718399920143949510880759960001\n",
      "1.0381398982549345E66\n"
     ]
    }
   ],
   "source": [
    "import java.math.BigInteger;\n",
    "\n",
    "BigInteger n = new BigInteger(\"1999\").pow(20);\n",
    "System.out.println(n);\n",
    "double d = n.doubleValue();\n",
    "System.out.println(d);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:07.877Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 26,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Integer i = 10;\n",
    "i.getClass();\n",
    "i instanceof Integer;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二，输入输出"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "输入：System.in, java.io.InputStreamReader, java.util.Scanner \n",
    "\n",
    "输出：System.out.println,  System.out.printf,  System.out.print\n",
    "\n",
    "读文件：java.io.FileInputStream\n",
    "\n",
    "写文件：java.io.FileOutputStream\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1, 输入**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Scanner扫描输入，遇到\\n结束\n",
    "\n",
    "BufferedReader.read() 逐字符读取\n",
    "\n",
    "BufferedReader.readLine() 逐行读取"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:17.724Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Input your name: LiLei\n",
      "Input your age: 12\n",
      "Hi, LiLei, you are 12\n"
     ]
    }
   ],
   "source": [
    "//Scanner扫描输入，遇到\\n结束\n",
    "\n",
    "import java.util.Scanner;\n",
    "\n",
    "public class Main {\n",
    "    public static void main(String[] args) {\n",
    "        Scanner scanner = new Scanner(System.in); // 创建Scanner对象\n",
    "        System.out.print(\"Input your name: \"); // 打印提示\n",
    "        String name = scanner.nextLine(); // 读取一行输入并获取字符串\n",
    "        System.out.print(\"Input your age: \"); // 打印提示\n",
    "        int age = scanner.nextInt(); // 读取一行输入并获取整数\n",
    "        System.out.printf(\"Hi, %s, you are %d\\n\", name, age); // 格式化输出\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:19.419Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "输入字符, 按下 'q' 键退出。\n",
      "128q\n",
      "1\n",
      "2\n",
      "8\n",
      "q\n"
     ]
    }
   ],
   "source": [
    "// BufferedReader.read() 逐字符读取\n",
    "import java.io.*;\n",
    " \n",
    "public class BRRead {\n",
    "    public static void main(String args[]) throws IOException {\n",
    "        char c;\n",
    "        // 使用 System.in 创建 BufferedReader\n",
    "        BufferedReader br = new BufferedReader(\n",
    "            new InputStreamReader(System.in));\n",
    "        System.out.println(\"输入字符, 按下 'q' 键退出。\");\n",
    "        // 读取字符\n",
    "        do {\n",
    "            c = (char) br.read();\n",
    "            System.out.println(c);\n",
    "        } while (c != 'q');\n",
    "    }\n",
    "}\n",
    "\n",
    "BRRead.main(new String[]{});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:21.070Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Enter lines of text.\n",
      "Enter 'end' to quit.\n",
      "hello world\n",
      "hello world\n",
      "end\n",
      "end\n"
     ]
    }
   ],
   "source": [
    "// BufferedReader.readLine() 逐行读取\n",
    "import java.io.*;\n",
    " \n",
    "public class BRReadLines {\n",
    "    public static void main(String args[]) throws IOException {\n",
    "        // 使用 System.in 创建 BufferedReader\n",
    "        BufferedReader br = new BufferedReader(\n",
    "            new InputStreamReader(System.in));\n",
    "        String str;\n",
    "        System.out.println(\"Enter lines of text.\");\n",
    "        System.out.println(\"Enter 'end' to quit.\");\n",
    "        do {\n",
    "            str = br.readLine();\n",
    "            System.out.println(str);\n",
    "        } while (!str.equals(\"end\"));\n",
    "    }\n",
    "}\n",
    "\n",
    "BRReadLines.main(new String[]{});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，输出**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "print不换行，println换行，printf格式化输出"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:32.288Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "helloworld"
     ]
    }
   ],
   "source": [
    "System.out.print(\"hello\");\n",
    "System.out.print(\"world\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:38.951Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n",
      "hello java\n"
     ]
    }
   ],
   "source": [
    "System.out.println(\"hello world\");\n",
    "System.out.println(\"hello java\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:15+0000",
     "start_time": "2019-09-15T03:15:54.385Z"
    }
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "error\n"
     ]
    }
   ],
   "source": [
    "System.err.println(\"error\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:54.091Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "name = LiLei, age = 18, weight = 34.0"
     ]
    },
    {
     "data": {
      "text/plain": [
       "java.io.PrintStream@6ada336a"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "String name = \"LiLei\";\n",
    "int age = 18;\n",
    "double weight = 34.0;\n",
    "System.out.printf(\"name = %s, age = %d, weight = %s\",name,age,weight);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3，读文件**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:39+0000",
     "start_time": "2019-09-14T12:39:59.314Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1\n",
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "\n"
     ]
    }
   ],
   "source": [
    "import java.io.*;\n",
    " \n",
    "public class ReadFileTest {\n",
    "    public static void main(String[] args) throws IOException {\n",
    "        File f = new File(\"data.txt\");\n",
    "        FileInputStream stream = new FileInputStream(f);\n",
    "        InputStreamReader reader = new InputStreamReader(stream, \"UTF-8\");\n",
    "        StringBuffer buffer = new StringBuffer();\n",
    "        while (reader.ready()) {\n",
    "            buffer.append((char) reader.read());\n",
    "        }\n",
    "        System.out.println(buffer.toString());\n",
    "        reader.close();\n",
    "        stream.close(); \n",
    "    }\n",
    "}\n",
    "\n",
    "ReadFileTest.main(new String[]{});"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4，写文件**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:40+0000",
     "start_time": "2019-09-14T12:40:39.952Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.io.*;\n",
    " \n",
    "public class WriteFileTest {\n",
    "    public static void main(String[] args) throws IOException {\n",
    " \n",
    "        File f = new File(\"test.txt\");\n",
    "        FileOutputStream stream = new FileOutputStream(f);\n",
    "        OutputStreamWriter writer = new OutputStreamWriter(stream,\"UTF-8\");\n",
    "        writer.append(\"中文输入\");\n",
    "        writer.append(\"\\r\\n\");\n",
    "        writer.append(\"English\");\n",
    "        writer.close();\n",
    "        stream.close();\n",
    "    }\n",
    "}\n",
    "\n",
    "WriteFileTest.main(new String[]{});\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 三，导入包package"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "java有以下一些导入包的方式：\n",
    "\n",
    "1，导入包中某个对象： import java.text.SimpleDateFormat\n",
    "\n",
    "2，导入包中全部对象: import java.util.*\n",
    "\n",
    "3，导入包中的静态字段和方法(较少使用): import static java.lang.System.*\n",
    "\n",
    "4，默认导入: java默认导入了java.lang.* \n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:40+0000",
     "start_time": "2019-09-14T12:40:54.758Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2019-09-16 08:16:51\n"
     ]
    }
   ],
   "source": [
    "//不导入，直接使用全名\n",
    "\n",
    "java.util.Date dt = new java.util.Date();\n",
    "java.text.SimpleDateFormat ft = \n",
    "    new java.text.SimpleDateFormat(\"yyyy-MM-dd hh:mm:ss\");\n",
    "System.out.println(ft.format(dt));\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:06.254Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2019-09-16 08:16:55\n",
      "24%\n"
     ]
    }
   ],
   "source": [
    "//导入包中某个对象\n",
    "import java.util.Date;\n",
    "import java.text.SimpleDateFormat;\n",
    "import java.text.NumberFormat;\n",
    "\n",
    "Date dt = new Date();\n",
    "SimpleDateFormat ft = new SimpleDateFormat(\"yyyy-MM-dd hh:mm:ss\");\n",
    "System.out.println(ft.format(dt));\n",
    "\n",
    "String s = java.text.NumberFormat.getPercentInstance().format(0.2393);\n",
    "System.out.println(s);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:14.470Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2019-09-16 08:16:58\n",
      "24%\n"
     ]
    }
   ],
   "source": [
    "//导入包中全部对象\n",
    "import java.util.*;\n",
    "import java.text.*;\n",
    "    \n",
    "Date dt = new Date();\n",
    "SimpleDateFormat ft = new SimpleDateFormat(\"yyyy-MM-dd hh:mm:ss\");\n",
    "System.out.println(ft.format(dt));\n",
    "String s = NumberFormat.getPercentInstance().format(0.2393);\n",
    "\n",
    "System.out.println(s);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:24.802Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "//导入包中的静态字段和方法\n",
    "import static java.lang.System.*;\n",
    "out.println(\"hello world\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:26.861Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello world\n"
     ]
    }
   ],
   "source": [
    "//java默认导入了java.lang.*\n",
    "System.out.println(\"hello world\");\n",
    "\n",
    "//等价于java.lang.System.out.println(\"hello world\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 四，语法规则"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1,标识符**\n",
    "\n",
    "标识符由字母和数字组成，遵循驼峰命名规则。\n",
    "\n",
    "类的名称以大写字母开头。\n",
    "\n",
    "方法的名称以小写字母开头。\n",
    "\n",
    "变量的名称以小写字母开头。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:35.418Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello LiLei!\n"
     ]
    }
   ],
   "source": [
    "public class Greeting{\n",
    "    public static void main(String[] args){\n",
    "        String person = \"LiLei\";\n",
    "        System.out.println(\"Hello \"+ person + \"!\");\n",
    "    }\n",
    "}\n",
    "\n",
    "Greeting.main(new String[]{});\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "2，注释\n",
    "\n",
    "单行注释用//开头\n",
    "多行注释用/*开头，以*/结尾包括\n",
    "\n",
    "特殊多行注释，以/**开头，以*/结束，如果有多行，每行通常以星号开头\n",
    "这种特殊的多行注释需要写在类和方法的定义处，可以用于自动创建文档。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:50.048Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, java!\n"
     ]
    }
   ],
   "source": [
    "/*\n",
    "多行注释\n",
    "author: Python与算法之美\n",
    "*/\n",
    "\n",
    "public class Greeting{\n",
    "    public void say(String towho){\n",
    "        System.out.println(\"Hello, \"+ towho + \"!\");\n",
    "    }\n",
    "}\n",
    "Greeting greet = new Greeting();//实例化一个对象 \n",
    "greet.say(\"java\");//调用对象的方法\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:41+0000",
     "start_time": "2019-09-14T12:41:55.016Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello, world!\n"
     ]
    }
   ],
   "source": [
    "/**\n",
    " * 特殊多行注释\n",
    " * 可以用来自动创建文档的注释\n",
    " * author:Python与算法之美\n",
    " */\n",
    "\n",
    "public class Greeting{\n",
    "    public static void main(String[] args){\n",
    "        System.out.println(\"Hello, world!\");\n",
    "    }\n",
    "}\n",
    "\n",
    "Greeting.main(new String[]{}); //调用静态方法\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3，数据类型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java 的数据类型有两大类，基本数据类型和引用数据类型。\n",
    "\n",
    "基本数据类型相对非常底层，基本类型相同值得对象占有同样的存储单元，判断是否相等可以用 ==。\n",
    "\n",
    "引用数据类型本质上都是Class，相对抽象，引用类型相同值得对象占用不同的存储单元，判断是否相等应该用 equals方法。\n",
    "\n",
    "基本数据类型包括：整型(byte,short,int,long),浮点型(float,double),布尔类型(boolean),字符类型(char)\n",
    "\n",
    "引用数据类型包括：包装类型(Integer,Double,Char,Boolean,……)，字符串(String),数组(Array),以及各种容器类(List,Map,Set,Queue)。\n",
    "\n",
    "用户自定义的任何Class都可以看成是一种引用数据类型。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-14T12:43+0000",
     "start_time": "2019-09-14T12:43:17.707Z"
    }
   },
   "outputs": [],
   "source": [
    "//基本数据类型\n",
    "byte i = 2;\n",
    "int j = 134;\n",
    "long k = 1234233;\n",
    "double y =2332.2332;\n",
    "char c = 'h';"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-01T12:33+0000",
     "start_time": "2019-09-01T12:33+0000"
    }
   },
   "outputs": [],
   "source": [
    "//包装类型 \n",
    "\n",
    "//包装类型只是在基本类型基础上做了一个Wrapper增加了一些方法，使得其成为一个引用类型。\n",
    "\n",
    "Integer i = 100;\n",
    "int a = i.value //转换成基本类型\n",
    "System.out.println(i.getClass().getSimpleName())\n",
    "\n",
    "Character c = 'A'\n",
    "char z = c.value //转换成基本类型\n",
    "System.out.println(a.toString())\n",
    "\n",
    "c instanceof Object\n",
    "\n",
    "Class cls = c.getClass()\n",
    "System.out.println(cls.getSimpleName())\n",
    "\n",
    "\n",
    "//包装类型和基本类型可以通过自动拆箱和自动装箱相互转换\n",
    "\n",
    "Integer m = Integer.valueOf(5) //自动装箱\n",
    "int n = m //自动拆箱\n",
    "\n",
    "n.getClass().getSimpleName()  //自动装箱\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:00+0000",
     "start_time": "2019-09-15T03:00:45.164Z"
    }
   },
   "outputs": [],
   "source": [
    "// String 字符串\n",
    "//字符串是一种引用类型, 并且是不可变的\n",
    "\n",
    "String  s = \"hello world\";\n",
    "System.out.println(s.getClass().getSimpleName());\n",
    "\n",
    "System.out.println(s.substring(0,5));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:01+0000",
     "start_time": "2019-09-15T03:01:10.192Z"
    }
   },
   "outputs": [],
   "source": [
    "// Array  数组\n",
    "// 数组是一种引用类型，其元素是可变的，但是其长度是不可变的\n",
    "String[] dogs = new String[2];\n",
    "dogs[0] = \"snoopy\";\n",
    "dogs[1] = \"ahuang\";\n",
    "\n",
    "System.out.println(dogs.length);\n",
    "\n",
    "System.out.println(dogs[0]);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:04+0000",
     "start_time": "2019-09-15T03:04:23.788Z"
    }
   },
   "outputs": [],
   "source": [
    "//基本类型和引用类型的对比\n",
    "\n",
    "//基本类型可以直接用==判断是否相等\n",
    "int i = 100823;\n",
    "int j = 100823;\n",
    "System.out.println(i==j);\n",
    "\n",
    "\n",
    "//引用类型必须要用equals方法进行判断\n",
    "Integer p = 123456;\n",
    "Integer q = 123450 + 6;\n",
    "\n",
    "System.out.println(p==q); //输出为false\n",
    "System.out.println(Objects.equals(p,q));//输出为true\n",
    "System.out.println(p.equals(q));//输出为true\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4，变量声明"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:05+0000",
     "start_time": "2019-09-15T03:05:34.210Z"
    }
   },
   "outputs": [],
   "source": [
    "//变量声明时可以先声明，后赋值。\n",
    "//也可以声明的同时初始化\n",
    "\n",
    "String a,b,c ; //声明三个变量a,b,c,不初始化，默认初始化为null\n",
    "\n",
    "a = \"xyz\";\n",
    "b = \"123\";\n",
    "\n",
    "System.out.println(a);\n",
    "System.out.println(c);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:05+0000",
     "start_time": "2019-09-15T03:05:37.558Z"
    }
   },
   "outputs": [],
   "source": [
    "//变量声明的同时初始化\n",
    "\n",
    "int i,j,k = 0;\n",
    "System.out.println(k)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:06+0000",
     "start_time": "2019-09-15T03:06:06.534Z"
    }
   },
   "outputs": [],
   "source": [
    "//使用final关键字声明为常量\n",
    "\n",
    "final double z = 3.14;\n",
    "System.out.println(z);\n",
    "\n",
    "//z = 5.12  将报错误，不可以被修改"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "5，标点符号"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java 中常用的标点符号用法总结如下\n",
    "\n",
    "()表示优先级或者函数参数列表\n",
    "\n",
    "[]用于索引\n",
    "\n",
    "{}用于作用域\n",
    "\n",
    "<>用于泛型\n",
    "\n",
    "@用于注解\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 五，编译执行"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1, 程序结构\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "一个.java程序文件中必须有且只有一个public类，该类必须有一个声明为main函数作为程序入口。\n",
    "\n",
    "并且这个main函数需要声明为 public static void 类型，即静态的，公开的，返回值为空的函数类型。\n",
    "\n",
    "并且这个java程序的文件名必须和这个public类名保持一致。\n",
    "\n",
    "下面是一个范例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:06+0000",
     "start_time": "2019-09-15T03:06:32.520Z"
    }
   },
   "outputs": [],
   "source": [
    "public class Demo {\n",
    "    public static void main(String[] args) {\n",
    "        Person lilei = new Person(\"LiLei\",18);\n",
    "        System.out.println(\"Hello, \" + lilei.getName());\n",
    "    }\n",
    "}\n",
    "\n",
    "class Person {\n",
    "    private String name;\n",
    "    private int age;\n",
    "\n",
    "    public Person(String name,Integer age){\n",
    "        this.name = name;\n",
    "        this.age = age;\n",
    "    }\n",
    "\n",
    "    public String getName() {\n",
    "        return this.name;\n",
    "    }\n",
    "\n",
    "    public int getAge() {\n",
    "        return this.age;\n",
    "    }\n",
    "}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "将以上代码拷贝到文本文件中，命名为 Main.java。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "2，编译执行"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java是一种解释型语言，其java源码需要被编译成class字节码运行在Java虚拟机上。\n",
    "\n",
    "因此，执行Java程序分两步：\n",
    "\n",
    "(1)，使用javac编译命令将以.java结束的程序文件编译成以class结尾的字节码程序文件。\n",
    "\n",
    "javac Main.java 编译后得到 Main.class文件\n",
    "\n",
    "(2)，使用java 命令运行字节码程序。\n",
    "\n",
    "java -classpath ./ Main 在JVM上执行Main.class文件"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](java解释型.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "编译时，按下面的顺序依次查找类：\n",
    "\n",
    "（1）查找当前package是否存在这个class；\n",
    "\n",
    "（2）查找import的包是否包含这个class；\n",
    "\n",
    "（3）查找java.lang包是否包含这个class。\n",
    "\n",
    "如果按照上面的规则还无法确定类名，则编译报错。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3，classpath和jar包"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（1） classpath \n",
    "\n",
    "classpath是JVM用到的一个环境变量，它用来指示JVM如何搜索class。\n",
    "\n",
    "它其实就是一组目录的集合，它设置的搜索路径与操作系统相关。\n",
    "\n",
    "例如，在Windows系统上，用;分隔，可能长这样。\n",
    "\n",
    "C:\\work\\project1\\bin;C:\\shared;\"D:\\My Documents\\project1\\bin\"\n",
    "\n",
    "在Linux系统上，用:分隔，可能长这样。\n",
    "\n",
    "/usr/shared:/usr/local/bin:/home/liaoxuefeng/bin\n",
    "\n",
    "如果JVM在某个路径下找到了对应的class文件，就不再往后继续搜索。如果所有路径下都没有找到，就报错。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "classpath的设定方法有两种：\n",
    "\n",
    "在系统环境变量中设置classpath环境变量，不推荐；\n",
    "\n",
    "在启动JVM时设置classpath变量，推荐。\n",
    "\n",
    "\n",
    "我们强烈不推荐在系统环境变量中设置classpath，那样会污染整个系统环境。\n",
    "\n",
    "在启动JVM时设置classpath才是推荐的做法。实际上就是给java命令传入-classpath或-cp参数：\n",
    "\n",
    "java -classpath .;C:\\work\\project1\\bin;C:\\shared abc.xyz.Hello\n",
    "\n",
    "但通常classpath这个参数不需要配置，其默认值为当前目录 ./一般就够用了。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "（2） jar包\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "设想一下，如果有很多.class文件，散落在各层目录中，肯定不便于管理。\n",
    "\n",
    "如果能把目录打一个包，变成一个文件，就方便多了。\n",
    "\n",
    "jar包就是用来干这个事的，它可以把package组织的目录层级，以及各个目录下的所有文件\n",
    "\n",
    "（包括.class文件和其他文件）都打成一个jar文件，这样一来，无论是备份，还是发给客户，就简单多了。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "jar包实际上就是一个zip格式的压缩文件，而jar包相当于目录。\n",
    "\n",
    "如果我们要执行一个jar包的class，就可以把jar包放到classpath中：\n",
    "\n",
    "java -cp ./hello.jar abc.xyz.Hello"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "jar包还可以包含一个特殊的/META-INF/MANIFEST.MF文件，\n",
    "\n",
    "MANIFEST.MF是纯文本，可以指定Main-Class和其它信息。\n",
    "\n",
    "JVM会自动读取这个MANIFEST.MF文件。\n",
    "\n",
    "如果存在Main-Class，我们就不必在命令行指定启动的类名，而是用更方便的命令：\n",
    "\n",
    "java -jar hello.jar\n",
    "\n",
    "jar包还可以包含其它jar包，这个时候，就需要在MANIFEST.MF文件里配置classpath了"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "4，maven项目管理工具"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实际项目开发中，通常使用maven管理项目，并打成jar包。\n",
    "\n",
    "maven使用POM文件POM.xml指定项目的依赖和打包方式。\n",
    "\n",
    "maven安装后，将会在本地创建~/.m2/repository目录，集中存放jar包作为本地仓库。\n",
    "\n",
    "maven搜索并载入依赖的顺序如下：本地仓库->私人远程仓库->中央仓库\n",
    "\n",
    "常见的maven 命令如下：\n",
    "\n",
    "mvn clean\n",
    "\n",
    "mvn compile       编译 \n",
    "\n",
    "mvn package       根据build中的plugin进行打包\n",
    "\n",
    "mvn install       安装本地仓库\n",
    "\n",
    "mvn test          单元测试\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 六，Java数据结构概述"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java中常用的数据结构主要包括字符串(String),数组(Array),枚举(enum), 以及java.util中的各种容器类（通常被称做集合）。\n",
    "\n",
    "java.util中的这些容器类分成两大类，一类是实现了Collection接口,另外一类实现了Map接口。\n",
    "\n",
    "容器类中常用的数据结构包括:列表(List),映射(Map),集合(Set),队列(Quene),堆栈(Stack)。\n",
    "\n",
    "当然这些数据结构也都是接口，通过API封装了特定的功能，下面还会有多种不同的实现。\n",
    "\n",
    "可以用统一的Iterator方式对大多数容器类进行遍历，这种更加抽象的方式优于使用下标的方式进行遍历。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](Java容器.gif)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 七，字符串"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T03:07+0000",
     "start_time": "2019-09-15T03:07:20.511Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.lang.String"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java 中的字符串和Scala中的字符串来源于同一个包，java.lang.String，两者具有完全相同的方法。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建字符串**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T08:22+0000",
     "start_time": "2019-09-15T08:21:59.931Z"
    }
   },
   "outputs": [],
   "source": [
    "String s1= \"hello world\";\n",
    "String s2 = \"hello China\";\n",
    "//Java 不支持多行字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，字符串常用操作**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:15+0000",
     "start_time": "2019-09-15T06:15:44.567Z"
    }
   },
   "outputs": [],
   "source": [
    "//+号字符串连接\n",
    "String s1 = \"hello world\";\n",
    "String s2 = \"hello China\";\n",
    "\n",
    "s1+\"\\t\"+s2;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:16+0000",
     "start_time": "2019-09-15T06:16:06.282Z"
    }
   },
   "outputs": [],
   "source": [
    "//concat字符串连接\n",
    "String s1 = \"hello world\";\n",
    "s1.concat(\" hello Beijing\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:16+0000",
     "start_time": "2019-09-15T06:16:12.940Z"
    }
   },
   "outputs": [],
   "source": [
    "//字符串长度\n",
    "String s1 = \"hello world\";\n",
    "s1.length()  //注意length（）是个方法\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:16+0000",
     "start_time": "2019-09-15T06:16:50.035Z"
    }
   },
   "outputs": [],
   "source": [
    "//取某个字符的下标\n",
    "String s1 = \"hello world\";\n",
    "s1.indexOf(\" \");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:17+0000",
     "start_time": "2019-09-15T06:17:00.047Z"
    }
   },
   "outputs": [],
   "source": [
    "//取某个子串\n",
    "String s1 = \"hello world\";\n",
    "s1.substring(2,6);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-08T09:33+0000",
     "start_time": "2019-09-08T09:33+0000"
    }
   },
   "outputs": [],
   "source": [
    "//字符串替换\n",
    "String s1 = \"hello world\";\n",
    "s1.replace(\"world\",\"China\");\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-08T04:03+0000",
     "start_time": "2019-09-08T04:03+0000"
    }
   },
   "outputs": [],
   "source": [
    "//字符串分割\n",
    "String s1 = \"hello world\";\n",
    "System.out.println(s1.split(\" \"));"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 八，数组"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java 中的数组和 C++中的数组很像，其长度是不可变的，但是数组中的元素内容是可以改变的。\n",
    "\n",
    "数组是引用类型。\n",
    "\n",
    "在大多数版本的Java中，数组是用花括号{}作为数组范围标识的。\n",
    "\n",
    "不过在SciJava中数组是用方括号[]作为数组范围标识的。\n",
    "\n",
    "java.util.Arrays 类能方便地操作数组，它提供的所有方法都是静态的。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1,创建数组**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:34+0000",
     "start_time": "2019-09-15T06:34:49.980Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.Arrays;\n",
    "\n",
    "int[] arr = new int[5];\n",
    "for(int i=0;i<arr.length;i++){\n",
    "    arr[i]=i+1;\n",
    "}\n",
    "arr[1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:40.096Z"
    }
   },
   "outputs": [],
   "source": [
    "String[] arr = new String[] {\"Java\",\"C\",\"C++\",\"Python\",\"JavaScript\"};\n",
    "System.out.println(Arrays.asList(arr)); //转换成List方便打印\n",
    "\n",
    "arr[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:15.154Z"
    }
   },
   "outputs": [],
   "source": [
    "String[] arr = {\"hello\",\"world\",\"hello\",\"China\"};\n",
    "arr[3]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:26.867Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.Arrays;\n",
    "double[] arr = new double[10];\n",
    "Arrays.fill(arr,1.0);\n",
    "arr[2];"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:44.018Z"
    }
   },
   "outputs": [],
   "source": [
    "//多维数组\n",
    "double[][] arr = {{1.0,2.0},{3.0,4.0},{5.0,6.0}};\n",
    "System.out.println(arr[0][1])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，数组的常用操作**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:47.554Z"
    }
   },
   "outputs": [],
   "source": [
    "//数组的取值和赋值\n",
    "\n",
    "String[] arr = {\"hello\",\"world\"};\n",
    "arr[1] = \"China\";\n",
    "System.out.println(arr[0]+arr[1]);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:50.420Z"
    }
   },
   "outputs": [],
   "source": [
    "//数组的切片\n",
    "import java.util.Arrays;\n",
    "String[] arr = {\"Java\",\"C++\",\"Python\",\"JavaScript\"};\n",
    "\n",
    "String[] subarr = Arrays.copyOfRange(arr,1,4);\n",
    "System.out.println(Arrays.asList(subarr));\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:53.086Z"
    }
   },
   "outputs": [],
   "source": [
    "//数组的遍历\n",
    "String[] arr = {\"Java\",\"C++\",\"Python\",\"JavaScript\"};\n",
    "//使用foreach语法\n",
    "for(String x: arr){\n",
    "    System.out.println(x);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:56.154Z"
    }
   },
   "outputs": [],
   "source": [
    "//数组排序\n",
    "import java.util.Arrays;\n",
    "Double[] arr = {1.00,3.14,0.618,1.414};\n",
    "Arrays.sort(arr);\n",
    "System.out.println(Arrays.asList(arr));\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:35+0000",
     "start_time": "2019-09-15T06:35:58.898Z"
    }
   },
   "outputs": [],
   "source": [
    "//判断两个数组是否相等\n",
    "import java.util.Arrays;\n",
    "String[] arr1 = {\"hello\",\"world\"};\n",
    "String[] arr2 = {\"hello\",\"China\"};\n",
    "Arrays.equals(arr1,arr2);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 九，列表List"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java中的列表List是一种有序数据结构的接口。\n",
    "\n",
    "它有两种实现,一种是ArrayList,另外一种是LinkedList.\n",
    "\n",
    "前者是顺序存储，方便查询和修改特定元素。后者是链表存储，方便插入和删除元素。\n",
    "\n",
    "通常情况下我们使用ArrayList更多一些。\n",
    "\n",
    "和数组Array不同，List的大小是可以改变的。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "List的主要方法如下：（E是元素 e的类型）\n",
    "\n",
    "在末尾添加一个元素：void add(E e)\n",
    "\n",
    "在指定索引添加一个元素：void add(int index, E e)\n",
    "\n",
    "删除指定索引的元素：int remove(int index)\n",
    "\n",
    "删除某个元素：int remove(Object e)\n",
    "\n",
    "获取指定索引的元素：E get(int index)\n",
    "\n",
    "获取链表大小（包含元素的个数）：int size()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1,创建List**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:42+0000",
     "start_time": "2019-09-15T06:42:28.925Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = new ArrayList<>();\n",
    "list.add(1.0);\n",
    "list.add(2.0);\n",
    "list.add(3.0);\n",
    "\n",
    "System.out.println(list);\n",
    "System.out.println(list.getClass());"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:38+0000",
     "start_time": "2019-09-15T06:38:59.842Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "//List<String> list = List.of(\"apple\", \"pear\", \"banana\"); 标准的Java是这种语法\n",
    "List<String> list = List.of(\"apple\", \"pear\", \"banana\");\n",
    "list.getClass() //不可变List\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，List常用操作**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:45+0000",
     "start_time": "2019-09-15T06:45:14.927Z"
    }
   },
   "outputs": [],
   "source": [
    "//增加元素\n",
    "\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = new ArrayList<Double>(2); //初始化长度为2\n",
    "list.add(1.0);\n",
    "list.add(2.0);\n",
    "list.add(3.0);\n",
    "list;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:53+0000",
     "start_time": "2019-09-15T06:53:36.775Z"
    }
   },
   "outputs": [],
   "source": [
    "//删除指定索引位置的元素\n",
    "\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list =  new ArrayList<>();\n",
    "list.add(1.0);\n",
    "list.add(2.0);\n",
    "list.remove(1.0);\n",
    "list;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:54+0000",
     "start_time": "2019-09-15T06:54:10.468Z"
    }
   },
   "outputs": [],
   "source": [
    "//删除元素\n",
    "\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = new ArrayList<>();\n",
    "list.add(1.0);\n",
    "list.add(2.0);\n",
    "list.remove(1);\n",
    "list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:54+0000",
     "start_time": "2019-09-15T06:54:51.232Z"
    }
   },
   "outputs": [],
   "source": [
    "//获取元素\n",
    "\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = new ArrayList<>();\n",
    "list.add(1.0);\n",
    "list.add(2.0);\n",
    "list.get(1);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:55+0000",
     "start_time": "2019-09-15T06:55:06.020Z"
    }
   },
   "outputs": [],
   "source": [
    "//是否包含某个元素\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = List.of(1.0,2.0);\n",
    "list.contains(1.0);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:55+0000",
     "start_time": "2019-09-15T06:55:18.901Z"
    }
   },
   "outputs": [],
   "source": [
    "//查找某个元素下标\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = List.of(1.0,2.0);\n",
    "list.indexOf(2.0);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:55+0000",
     "start_time": "2019-09-15T06:55:32.961Z"
    }
   },
   "outputs": [],
   "source": [
    "//列表长度\n",
    "import java.util.ArrayList;\n",
    "import java.util.List;\n",
    "\n",
    "List<Double> list = List.of(1.0,2.0);\n",
    "list.size();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十，映射Map"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Map是一种无序数据结构的接口，存储键值对(key,value)。\n",
    "\n",
    "Map的常用实现是HashMap, LinkedHashMap, TreeMap.\n",
    "\n",
    "其中TreeMap是一种有序的Map.\n",
    "\n",
    "Map的常用方法是put和get.\n",
    "\n",
    "如果想查询某个key是否存在，可以调用containsKey.\n",
    "\n",
    "Map中的key是唯一的，作为key的对象必须实现equals和hashCode方法。\n",
    "\n",
    "使用TreeMap时，放入的Key必须实现Comparable接口。\n",
    "\n",
    "Map通常用来高效地进行查找。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，创建Map** "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:55+0000",
     "start_time": "2019-09-15T06:55:56.719Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.HashMap;\n",
    "import java.util.Map;\n",
    "\n",
    "Map<String, Integer> map = new HashMap<>();\n",
    "map.put(\"apple\", 123);\n",
    "map.put(\"pear\", 456);\n",
    "map.put(\"banana\", 789);\n",
    "\n",
    "System.out.println(map)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:59+0000",
     "start_time": "2019-09-15T06:59:53.620Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.HashMap;\n",
    "import java.util.Map;\n",
    "\n",
    "Map<String, Integer> map = Map.of(\"apple\", 123, \"pear\", 456, \"banana\", 789);  \n",
    "\n",
    "System.out.println(map);\n",
    "System.out.println(map.getClass()) //不可变的Map"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T06:55+0000",
     "start_time": "2019-09-15T06:55:49.416Z"
    }
   },
   "outputs": [],
   "source": [
    "//TreeMap是一种有序的Map，会对Key进行排序\n",
    "Map<String, Integer> map = new TreeMap<>();\n",
    "map.put(\"orange\", 1);\n",
    "map.put(\"apple\", 2);\n",
    "map.put(\"pear\", 3);\n",
    "for (String key : map.keySet()) {\n",
    "    System.out.println(key);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，Map常用操作** "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:00+0000",
     "start_time": "2019-09-15T07:00:40.803Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.HashMap;\n",
    "import java.util.Map;\n",
    "\n",
    "Map<String, Integer> map = new HashMap<>();\n",
    "map.put(\"apple\", 123);\n",
    "map.put(\"pear\", 456);\n",
    "map.put(\"banana\", 789);\n",
    "map.put(\"pineapple\",8); //增加key,value对\n",
    "\n",
    "System.out.println(map);\n",
    "\n",
    "System.out.println(map.get(\"apple\")); //取元素\n",
    "\n",
    "System.out.println(map.get(\"watermelon\")); //不存在的元素将返回null\n",
    "\n",
    "System.out.println(map.containsKey(\"watermelon\")); //测试是否包括元素\n",
    "\n",
    "System.out.println(map.getClass());"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:01+0000",
     "start_time": "2019-09-15T07:01:22.233Z"
    }
   },
   "outputs": [],
   "source": [
    "//Map的遍历，使用keyset()\n",
    "Map<String, Integer> map = Map.of(\"apple\", 123, \"pear\", 456, \"banana\", 789);  \n",
    "for (String key : map.keySet()) {\n",
    "    System.out.println(key);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:01+0000",
     "start_time": "2019-09-15T07:01:33.003Z"
    }
   },
   "outputs": [],
   "source": [
    "//Map的遍历，使用entrySet()，同时遍历key和value\n",
    "import java.util.HashMap;\n",
    "import java.util.Map;\n",
    "Map<String, Integer> map = new HashMap<>();\n",
    "map.put(\"apple\", 123);\n",
    "map.put(\"pear\", 456);\n",
    "map.put(\"banana\", 789);\n",
    "for (Map.Entry<String, Integer> entry : map.entrySet()) {\n",
    "    String key = entry.getKey();\n",
    "    Integer value = entry.getValue();\n",
    "    System.out.println(key + \" = \" + value);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十一，集合Set"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Set用于存储不重复的元素集合，它主要提供以下几个方法：\n",
    "\n",
    "将元素添加进Set<E>：boolean add(E e)\n",
    "    \n",
    "将元素从Set<E>删除：boolean remove(Object e)\n",
    "    \n",
    "判断是否包含元素：boolean contains(Object e)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:02+0000",
     "start_time": "2019-09-15T07:02:01.190Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.Set;\n",
    "import java.util.HashSet;\n",
    "public class Main {\n",
    "    public static void main(String[] args) {\n",
    "        Set<String> set = new HashSet<>();\n",
    "        System.out.println(set.add(\"abc\")); // true\n",
    "        System.out.println(set.add(\"xyz\")); // true\n",
    "        System.out.println(set.add(\"xyz\")); // false，添加失败，因为元素已存在\n",
    "        System.out.println(set.contains(\"xyz\")); // true，元素存在\n",
    "        System.out.println(set.contains(\"XYZ\")); // false，元素不存在\n",
    "        System.out.println(set.remove(\"hello\")); // false，删除失败，因为元素不存在\n",
    "        System.out.println(set.size()); // 2，一共两个元素\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十二，迭代器"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java的容器类都可以使用for each循环，List、Set和Queue会迭代每个元素，Map会迭代每个key。\n",
    "\n",
    "下面以List和Set的for each遍历为例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:02+0000",
     "start_time": "2019-09-15T07:02:23.232Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.List;\n",
    "List<String> list = List.of(\"Apple\", \"Orange\", \"Pear\");\n",
    "for (String s : list) {\n",
    "    System.out.println(s);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:02+0000",
     "start_time": "2019-09-15T07:02:39.514Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.Set;\n",
    "Set<String> set = Set.of(\"Apple\", \"Orange\", \"Pear\");\n",
    "for (String s : set) {\n",
    "    System.out.println(s);\n",
    "}\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "实际上，Java编译器并不知道如何遍历List和Set。\n",
    "\n",
    "上述代码能够编译通过，只是因为编译器把for each循环通过Iterator改写为了普通的for循环："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:03+0000",
     "start_time": "2019-09-15T07:03:22.683Z"
    }
   },
   "outputs": [],
   "source": [
    "import java.util.Set;\n",
    "Set<String> set = Set.of(\"apple\",\"orange\",\"pear\");\n",
    "for (Iterator<String> iter = set.iterator(); iter.hasNext(); ) {\n",
    "     String s = iter.next();\n",
    "     System.out.println(s);\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Iterator是一种抽象的数据访问模型。使用Iterator模式进行迭代的好处有：\n",
    "\n",
    "对任何容器都采用同一种访问模型；\n",
    "\n",
    "调用者对容器内部结构一无所知；\n",
    "\n",
    "容器类返回的Iterator对象知道如何迭代。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果我们自己编写了一个集合类，想要使用for each循环，则该集合类实现Iterable接口，并返回一个Iterator对象；\n",
    "\n",
    "下面是一个范例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:03+0000",
     "start_time": "2019-09-15T07:03:58.534Z"
    }
   },
   "outputs": [],
   "source": [
    "public class Main {\n",
    "    public static void main(String[] args) {\n",
    "        ReverseList<String> rlist = new ReverseList<>();\n",
    "        rlist.add(\"Apple\");\n",
    "        rlist.add(\"Orange\");\n",
    "        rlist.add(\"Pear\");\n",
    "        for (String s : rlist) {\n",
    "            System.out.println(s);\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "class ReverseList<T> implements Iterable<T> {\n",
    "\n",
    "    List<T> list = new ArrayList<>();\n",
    "\n",
    "    public void add(T t) {\n",
    "        list.add(t);\n",
    "    }\n",
    "\n",
    "    @Override\n",
    "    public Iterator<T> iterator() {\n",
    "        return new ReverseIterator(list.size());\n",
    "    }\n",
    "\n",
    "    class ReverseIterator implements Iterator<T> {\n",
    "        int index;\n",
    "\n",
    "        ReverseIterator(int index) {\n",
    "            this.index = index;\n",
    "        }\n",
    "\n",
    "        @Override\n",
    "        public boolean hasNext() {\n",
    "            return index > 0;\n",
    "        }\n",
    "\n",
    "        @Override\n",
    "        public T next() {\n",
    "            index--;\n",
    "            return ReverseList.this.list.get(index);\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十三，枚举类enum"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "如果有一些相关的常量，如星期，月份，颜色，可以将其它们定义为枚举类型。\n",
    "\n",
    "枚举类型常用的方法有name和ordinal。\n",
    "\n",
    "name():查看枚举常量值的名字。\n",
    "\n",
    "ordinal():查看枚举常量值的序号。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:04+0000",
     "start_time": "2019-09-15T07:04:10.056Z"
    }
   },
   "outputs": [],
   "source": [
    "enum Weekday {\n",
    "    SUN, MON, TUE, WED, THU, FRI, SAT;\n",
    "}\n",
    "\n",
    "Weekday day = Weekday.SUN;\n",
    "if (day == Weekday.SAT || day == Weekday.SUN) {\n",
    "    System.out.println(\"Work at home!\");\n",
    "} else {\n",
    "    System.out.println(\"Work at office!\");\n",
    "}\n",
    "\n",
    "System.out.println(day.name());\n",
    "\n",
    "System.out.println(day.ordinal());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过enum定义的枚举类，其实也是一个class，只不过它有以下几个特点：\n",
    "\n",
    "* 定义的enum类型总是继承自java.lang.Enum，且无法被继承；\n",
    "\n",
    "* 只能定义出enum的实例，而无法通过new操作符创建enum的实例；\n",
    "\n",
    "* 定义的每个实例都是引用类型的唯一实例；\n",
    "\n",
    "* 可以将enum类型用于switch语句。\n",
    "\n",
    "\n",
    "因为枚举类也是class,所以我们可以定义private的构造方法，并且，给每个枚举常量添加字段。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:04+0000",
     "start_time": "2019-09-15T07:04:15.643Z"
    }
   },
   "outputs": [],
   "source": [
    "enum Weekday {\n",
    "    MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0);\n",
    "\n",
    "    public final int dayValue;\n",
    "\n",
    "    private Weekday(int dayValue) {\n",
    "        this.dayValue = dayValue;\n",
    "    }\n",
    "}\n",
    "\n",
    "Weekday day = Weekday.SUN;\n",
    "if (day.dayValue == 6 || day.dayValue == 0) {\n",
    "    System.out.println(\"Work at home!\");\n",
    "} else {\n",
    "    System.out.println(\"Work at office!\");\n",
    "}\n",
    "\n",
    "\n",
    "day.ordinal();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十四，选择结构"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java的选择结构主要有 if 语句和 switch语句。 switch语句是多分支结构。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，if选择语句**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:05+0000",
     "start_time": "2019-09-15T07:05:10.737Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "//if...else...语句\n",
    "int a = 2;\n",
    "int b = 3;\n",
    "int m = a;\n",
    "if(a>b){\n",
    "    m = a;\n",
    "}else{\n",
    "    m = b;}\n",
    "\n",
    "System.out.println(m)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:05+0000",
     "start_time": "2019-09-15T07:05:03.111Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "3\n"
     ]
    }
   ],
   "source": [
    "//三目运算符\n",
    "int a = 2;\n",
    "int b = 3;\n",
    "int m = (a>b)?a:b;  //相当于Python和scala的单行if语句，但可读性更差。\n",
    "\n",
    "System.out.println(m);\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，switch多分支结构**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用switch语句时不要忘记break，不要忘记default."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:07+0000",
     "start_time": "2019-09-15T07:07:39.333Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "one\n",
      "two\n",
      "many\n"
     ]
    }
   ],
   "source": [
    "class Test{\n",
    "    public static void main(String[] args){\n",
    "        System.out.println(testSwitch(1));\n",
    "        System.out.println(testSwitch(2));\n",
    "        System.out.println(testSwitch(100));\n",
    "    }\n",
    "    static String testSwitch(int option){\n",
    "        String x = null;\n",
    "        switch(option){\n",
    "            case 1:\n",
    "                x = \"one\";\n",
    "                break;    \n",
    "            case 2:\n",
    "                x = \"two\";\n",
    "                break;\n",
    "            default:  //当没有匹配到任何case时，执行default：\n",
    "                x = \"many\";\n",
    "        } \n",
    "        return x;\n",
    "    }\n",
    "}\n",
    "\n",
    "Test.main(new String[]{\"abc\"});"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十五，循环结构"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java中的循环结构包括for循环，for each循环，while循环。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，for循环**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:11+0000",
     "start_time": "2019-09-15T07:11:43.652Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5050\n"
     ]
    }
   ],
   "source": [
    "//求1+2+3+...+100\n",
    "int sum = 0;\n",
    "for (int i=1; i<=100; i++) {\n",
    "    sum = sum + i;\n",
    "}\n",
    "System.out.println(sum);"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，for each循环**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "//for each循环可以对数组，字符串，各种容器类型进行遍历，其背后依赖于Iteratable接口。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:11+0000",
     "start_time": "2019-09-15T07:11:36.396Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "55\n"
     ]
    }
   ],
   "source": [
    "int[] arr = new int[] {1,2,3,4,5,6,7,8,9,10};\n",
    "int sum = 0;\n",
    "for (int i:arr) {  \n",
    "    sum = sum + i;\n",
    "}\n",
    "System.out.println(sum);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:10+0000",
     "start_time": "2019-09-15T07:10:54.256Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "h\n",
      "e\n",
      "l\n",
      "l\n",
      "o\n"
     ]
    }
   ],
   "source": [
    "String s = \"hello\";\n",
    "for (char c:s.toCharArray()) {  \n",
    "    System.out.println(c);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3，while循环**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-08T14:28+0000",
     "start_time": "2019-09-08T14:28+0000"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5050\n"
     ]
    }
   ],
   "source": [
    "//求1+2+3+...+100\n",
    "int i = 1;\n",
    "int s = 0;\n",
    "while(i<=100){\n",
    "    s = s + i;\n",
    "    i = i + 1;\n",
    "}\n",
    "System.out.println(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4，流程控制continue,break** "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:10+0000",
     "start_time": "2019-09-15T07:10:36.884Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "\n",
      "helloworld"
     ]
    }
   ],
   "source": [
    "String s = \"hello world\";\n",
    "\n",
    "//break跳出本层循环\n",
    "for(char c:s.toCharArray()){\n",
    "    if(c ==' '){\n",
    "        break;\n",
    "    }\n",
    "    System.out.print(c);\n",
    "    \n",
    "}\n",
    "\n",
    "System.out.println(\"\\n\");\n",
    "\n",
    "//continue跳过本次循环\n",
    "for(char c:s.toCharArray()){\n",
    "    if(c ==' '){\n",
    "        continue;\n",
    "    }\n",
    "    System.out.print(c);\n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:10+0000",
     "start_time": "2019-09-15T07:10:19.245Z"
    }
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十六，异常处理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![](Java异常体系.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java中的异常包括两种体系：Error和Exception.\n",
    "\n",
    "Error指的是严重的错误，程序一般对此无能为力。如：\n",
    "\n",
    "* OutOfMemoryError：内存耗尽\n",
    "* NoClassDefFoundError：无法加载某个Class\n",
    "* StackOverflowError：栈溢出\n",
    "\n",
    "而Exception则是运行时的错误，它可以被捕获并处理。\n",
    "\n",
    "某些异常是应用程序逻辑处理的一部分，应该捕获并处理。例如：\n",
    "\n",
    "* NumberFormatException：数值类型的格式错误\n",
    "* FileNotFoundException：未找到文件\n",
    "* SocketException：读取网络失败\n",
    "\n",
    "还有一些异常是程序逻辑编写不对造成的，应该修复程序本身。例如：\n",
    "\n",
    "* NullPointerException：对某个null的对象调用方法或字段\n",
    "* IndexOutOfBoundsException：数组索引越界\n",
    "\n",
    "Exception又分为两大类：\n",
    "\n",
    "* RuntimeException以及它的子类；\n",
    "* 非RuntimeException（包括IOException、ReflectiveOperationException等等）\n",
    "\n",
    "Java规定：\n",
    "\n",
    "必须捕获的异常，包括Exception及其子类，但不包括RuntimeException及其子类，这种类型的异常称为Checked Exception。\n",
    "\n",
    "不需要捕获的异常，包括Error及其子类，RuntimeException及其子类。\n",
    "\n",
    "\n",
    "异常捕获的语句是 try...catch...finally...此外还可以用throw抛出异常\n",
    "如：throw new IllegalArgumentException"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T07:08+0000",
     "start_time": "2019-09-15T07:08:31.476Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[-42, -48, -50, -60, -79, -32, -62, -21]\n"
     ]
    }
   ],
   "source": [
    "import java.io.UnsupportedEncodingException;\n",
    "import java.util.Arrays;\n",
    "\n",
    "public class Main {\n",
    "    public static void main(String[] args) {\n",
    "        try {\n",
    "            byte[] bs = toGBK(\"中文编码\");\n",
    "            System.out.println(Arrays.toString(bs));\n",
    "        } catch (UnsupportedEncodingException e) {\n",
    "            System.out.println(e);\n",
    "        }\n",
    "    }\n",
    "\n",
    "    static byte[] toGBK(String s) throws UnsupportedEncodingException {\n",
    "        // 用指定编码转换String为byte[]:\n",
    "        return s.getBytes(\"GBK\");\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十七，类的定义"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java中用关键字class定义普通类, 用enum定义枚举类,\n",
    "\n",
    "用abstract class定义抽象类，用interface定义接口。\n",
    "\n",
    "我们先看普通类的定义和实例化。\n",
    "\n",
    "类的定义中可以用public声明为公有属性和公有方法，在类的内部和外部都可以被访问。\n",
    "\n",
    "可以用private声明为私有属性和私有方法，只允许在类的作用域访问，不允许在类的外部访问。\n",
    "\n",
    "可以用protected声明为受保护的属性和方法，只允许在类作用域及其子类作用域中访问。\n",
    "\n",
    "不使用作用域关键字声明的属性和方法默认为为package作用域，在同一个package中的类可以访问。\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T08:36+0000",
     "start_time": "2019-09-15T08:36:38.108Z"
    }
   },
   "outputs": [],
   "source": [
    "//一个Dog类范例\n",
    "class Dog{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\"; //静态属性\n",
    "    public String name;\n",
    "    public String breed;\n",
    "    private double weight;\n",
    "    private int age;\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name,double weight,String breed,int age){\n",
    "        this.name = name;\n",
    "        this.weight = weight;\n",
    "        this.breed = breed;\n",
    "        this.age = age;\n",
    "    }\n",
    "    \n",
    "    public void run(){\n",
    "        System.out.println(this.name + \" is running...\");\n",
    "    }\n",
    "    \n",
    "    public void bark(){\n",
    "        System.out.println(\"Bowwow,Bowwow,Bowwow...\");\n",
    "    }\n",
    "    \n",
    "    public void sleep(){\n",
    "        System.out.println(\"Zzz...Zzz...Zzz...\");\n",
    "    }\n",
    "    \n",
    "    public void eat(String food){\n",
    "        System.out.printf(\"%s is eatting %s...\\n\",this.name,food);\n",
    "    }\n",
    "    \n",
    "    public void speak(String words){\n",
    "        think();\n",
    "        System.out.println(words);\n",
    "    }\n",
    "    \n",
    "    //私有方法\n",
    "    private void think(){\n",
    "        System.out.println(\"I feel myself a hero and very handsome !\");\n",
    "    }\n",
    "   \n",
    "}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T08:37+0000",
     "start_time": "2019-09-15T08:37:46.786Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Earth\n",
      "Earth\n",
      "snoopy\n",
      "snoopy is running...\n",
      "Bowwow,Bowwow,Bowwow...\n",
      "Zzz...Zzz...Zzz...\n",
      "snoopy is eatting fish...\n",
      "I feel myself a hero and very handsome !\n",
      "hahaha!\n"
     ]
    }
   ],
   "source": [
    "Dog snoopy = new Dog(\"snoopy\",2.50,\"Husky\",3);\n",
    "\n",
    "System.out.println(snoopy.home);\n",
    "System.out.println(Dog.home);\n",
    "System.out.println(snoopy.name); \n",
    "\n",
    "snoopy.run();\n",
    "snoopy.bark();\n",
    "snoopy.sleep();\n",
    "snoopy.eat(\"fish\");\n",
    "//snoopy.think(); 直接调用私有方法将报错！\n",
    "snoopy.speak(\"hahaha!\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十八，构造方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "构造方法是类的一个特殊的方法，构造方法名就是类名。\n",
    "\n",
    "构造方法没有return返回值，也没有void声明。\n",
    "\n",
    "如果一个类没有定义任何构造方法，那么编译器会自动为我们生成一个默认构造方法，它没有参数，也没有执行语句。\n",
    "\n",
    "如果我们已经定义了构造方法，那么编译器不会生成默认构造方法。\n",
    "\n",
    "没有在构造方法中初始化属性时，引用类型的字段默认是null，int类型默认值是0，布尔类型默认值是false。\n",
    "\n",
    "我们可以为一个类定义多个构造方法，使用时可以根据参数类型和数量自动进行匹配。\n",
    "\n",
    "这叫做构造方法的重载。\n",
    "\n",
    "所有方法都支持方法重载。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T08:44+0000",
     "start_time": "2019-09-15T08:44:09.264Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "null\n",
      "Husky\n"
     ]
    }
   ],
   "source": [
    "class Dog{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\";\n",
    "    public String name; //初始化为null\n",
    "    public String breed; //初始化为null\n",
    "    public double weight; //初始化为 0.0\n",
    "    public int age; //初始化为0\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name){\n",
    "        this.name = name;\n",
    "    }\n",
    "    \n",
    "    //构造方法重载，2个参数\n",
    "    public Dog(String name, String breed){\n",
    "        this.name = name;\n",
    "        this.breed = breed;\n",
    "    }\n",
    "    \n",
    "    //构造方法重载，3个参数\n",
    "    public Dog(String name, String breed, double weight, int age){\n",
    "        this.name = name;\n",
    "        this.breed = breed;\n",
    "        this.weight = weight;\n",
    "        this.age = age;\n",
    "    }\n",
    "}\n",
    "\n",
    "//调用只有一个参数的构造方法\n",
    "Dog snoopy = new Dog(\"snoopy\");\n",
    "System.out.println(snoopy.breed);\n",
    "\n",
    "//调用有2个参数的构造方法\n",
    "Dog snoopy = new Dog(\"snoopy\",\"Husky\");\n",
    "System.out.println(snoopy.breed);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 十九，静态属性和静态方法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通过static修饰的属性为静态属性，通过static修饰的方法为静态方法。\n",
    "\n",
    "静态属性和静态方法属于类而不属于特定的实例，在类的实例之间共享。\n",
    "\n",
    "可以通过类名直接调用静态属性和静态方法，也可以通过实例对象间接调用。\n",
    "\n",
    "静态方法中不能够通过this关键字使用实例属性。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T09:00+0000",
     "start_time": "2019-09-15T09:00:50.253Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Earth\n",
      "No deal, No hurt!\n",
      "Earth\n",
      "No deal, No hurt!\n",
      "Jupiter\n",
      "Jupiter\n"
     ]
    }
   ],
   "source": [
    "class Dog{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\";\n",
    "    public String name; //初始化为null\n",
    "    \n",
    "    //静态方法\n",
    "    public static void dream(){\n",
    "        System.out.println(\"No deal, No hurt!\");\n",
    "    }\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name){\n",
    "        this.name = name;\n",
    "    }\n",
    "\n",
    "}\n",
    "\n",
    "//通过类名调用静态属性和静态方法\n",
    "System.out.println(Dog.home);\n",
    "Dog.dream();\n",
    "\n",
    "//通过实例调用静态属性和静态方法\n",
    "Dog snoopy = new Dog(\"snoopy\");\n",
    "System.out.println(snoopy.home);\n",
    "snoopy.dream();\n",
    "\n",
    "//如果某个实例修改了静态属性，则全部实例该属性都遭到了修改\n",
    "//dangerous!\n",
    "Dog dollar = new Dog(\"dollar\");\n",
    "dollar.home = \"Jupiter\";\n",
    "System.out.println(dollar.home);\n",
    "System.out.println(snoopy.home);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十，继承"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "类和类之间有三种关系，A is B, A use B, A has B.\n",
    "\n",
    "其中A is B 就是 继承关系。\n",
    "\n",
    "如果A 的属性中有 B的类型，叫做 A has B.\n",
    "\n",
    "如果A 的方法的参数中有 B的类型，叫做 A use B.\n",
    "\n",
    "我们重点介绍继承关系。\n",
    "\n",
    "Java中用extends声明继承关系。\n",
    "\n",
    "public, protected声明的属性和方法可以被子类继承，\n",
    "\n",
    "而private声明的属性和方法不可以被子类继承。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T09:40+0000",
     "start_time": "2019-09-15T09:40:11.244Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "snoopy is calling: Bowwow,Bowwow,Bowwow...\n",
      "Dog\n"
     ]
    }
   ],
   "source": [
    "class Animal{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\";\n",
    "    public String name; //初始化为null\n",
    "    protected double weight; //protected 声明的属性和方法可以被继承\n",
    "    \n",
    "    //构造方法\n",
    "    public Animal(String name,double weight){\n",
    "        this.name = name;\n",
    "        this.weight = weight;\n",
    "    }\n",
    "    \n",
    "    public void call(){\n",
    "        System.out.print(this.name + \" is calling: \");\n",
    "    }\n",
    "    \n",
    "}\n",
    "\n",
    "class Dog extends Animal{\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name,double weight){\n",
    "        super(name,weight); //调用父类的构造方法\n",
    "    }\n",
    "    \n",
    "    @Override //加上@Override会进行覆盖检查，需要和父类的方法签名完全一致。\n",
    "    public void call(){\n",
    "        super.call();  //调用父类的方法\n",
    "        System.out.println(\"Bowwow,Bowwow,Bowwow...\");\n",
    "    }\n",
    "}\n",
    "\n",
    "//引用类型可以和实际类型不一致，此处引用类型为Animal，实际类型为Dog。\n",
    "Animal snoopy = new Dog(\"snoopy\",2.5); \n",
    "snoopy.call();\n",
    "System.out.println(snoopy.getClass().getSimpleName());"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十一，多态"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java的实例方法调用是基于运行时的实际类型的动态调用，而非变量的声明类型。\n",
    "\n",
    "这个非常重要的特性在面向对象编程中称之为多态。它的英文拼写非常复杂：Polymorphic。\n",
    "\n",
    "多态具有一个非常强大的功能，就是允许添加更多类型的子类实现功能扩展，却不需要修改基于父类的代码。\n",
    "\n",
    "这就实现了面向对象编程非常著名的开闭原则：对扩展开放，对修改封闭。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T09:54+0000",
     "start_time": "2019-09-15T09:54:31.388Z"
    }
   },
   "outputs": [],
   "source": [
    "class Animal{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\";\n",
    "    public String name; //初始化为null\n",
    "    protected double weight; //protected 声明的属性和方法可以被继承\n",
    "    \n",
    "    //构造方法\n",
    "    public Animal(String name,double weight){\n",
    "        this.name = name;\n",
    "        this.weight = weight;\n",
    "    }\n",
    "    \n",
    "    public void call(){\n",
    "        System.out.print(this.name + \" is calling: \");\n",
    "    }\n",
    "    \n",
    "}\n",
    "\n",
    "class Dog extends Animal{\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name,double weight){\n",
    "        super(name,weight); //调用父类的构造方法\n",
    "    }\n",
    "    \n",
    "    @Override //加上@Override会进行覆盖检查，需要和父类的方法签名完全一致。\n",
    "    public void call(){\n",
    "        super.call();  //调用父类的方法\n",
    "        System.out.println(\"Bowwow,Bowwow,Bowwow...\");\n",
    "    }\n",
    "}\n",
    "\n",
    "\n",
    "\n",
    "class Cat extends Animal{\n",
    "    \n",
    "    //构造方法\n",
    "    public Cat(String name,double weight){\n",
    "        super(name,weight); //调用父类的构造方法\n",
    "    }\n",
    "    \n",
    "    @Override \n",
    "    public void call(){\n",
    "        super.call();  //调用父类的方法\n",
    "        System.out.println(\"Miaow...Miaow...Miaow...\");\n",
    "    }\n",
    "}\n",
    "\n",
    "class Test{\n",
    "    public static void main(Animal a){\n",
    "        a.call();\n",
    "    }\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T09:56+0000",
     "start_time": "2019-09-15T09:56:58.518Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "snoopy is calling: Bowwow,Bowwow,Bowwow...\n",
      "kitty is calling: Miaow...Miaow...Miaow...\n"
     ]
    }
   ],
   "source": [
    "Animal snoopy = new Dog(\"snoopy\",2.5);\n",
    "Animal kitty = new Cat(\"kitty\",1.5);\n",
    "\n",
    "//扩展Animal的子类，Test类无需修改，符合开闭原则。\n",
    "Test.main(snoopy);\n",
    "Test.main(kitty);\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十二，抽象类"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用abstract声明的方法为抽象类，抽象类只能够被继承，不能够创建抽象类的实例。\n",
    "\n",
    "抽象类的方法可以被abstract声明为抽象方法，抽象方法没有执行语句。\n",
    "\n",
    "抽象类的作用在于定义签名规范，具体的业务实现留给子类去做。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T10:24+0000",
     "start_time": "2019-09-15T10:24:10.128Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Bowwow,Bowwow,Bowwow...\n"
     ]
    }
   ],
   "source": [
    "//包含抽象方法的类必须被定义为抽象类，抽象类不能被实例化。\n",
    "abstract class Animal{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\";\n",
    "    public String name; \n",
    "    \n",
    "    //构造方法\n",
    "    public Animal(String name){\n",
    "        this.name = name;\n",
    "    }\n",
    "    \n",
    "    abstract public void call(); //抽象方法只定义签名\n",
    "    \n",
    "}\n",
    "\n",
    "//继承自抽象类\n",
    "class Dog extends Animal{\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name){\n",
    "        super(name); //调用父类的构造方法\n",
    "    }\n",
    "    \n",
    "    //抽象方法的业务逻辑由子类来实现\n",
    "    @Override \n",
    "    public void call(){\n",
    "        System.out.println(\"Bowwow,Bowwow,Bowwow...\");\n",
    "    }\n",
    "}\n",
    "\n",
    "Animal snoopy = new Dog(\"snoopy\");\n",
    "snoopy.call();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十三，接口"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "在抽象类中，抽象方法本质上是定义接口规范：即规定高层类的接口，从而保证所有子类都有相同的接口实现，这样，多态就能发挥出威力。\n",
    "\n",
    "如果一个抽象类没有字段，所有方法全部都是抽象方法，那么该抽象类就可以被改写成接口(interface)。\n",
    "\n",
    "Java 中的 interface具有和 Scala中的 trait相似的功能。\n",
    "\n",
    "一个class只能继承自一个父类，但可以继承自多个接口。\n",
    "\n",
    "通过关键字 implements 声明class和interface之间的继承关系。\n",
    "\n",
    "interface和interface之间也可以相互继承，使用关键字 extends来表示这种扩展关系。\n",
    "\n",
    "interface不能有实例属性，但可以有静态属性。\n",
    "\n",
    "interface中的所有方法都默认为抽象方法，因此无需关键字abstract声明。\n",
    "\n",
    "interface的非抽象方法用default关键字声明，叫做default方法。\n",
    "\n",
    "default方法中不能够引用实例属性，但可以调用抽象方法。\n",
    "\n",
    "除了default方法和static声明的静态属性，interface基本上可以看成是一个躯壳。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:23+0000",
     "start_time": "2019-09-15T12:23:44.964Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "road\n",
      "snoopy is running in the road ...\n",
      "true\n",
      "true\n",
      "true\n",
      "true\n"
     ]
    }
   ],
   "source": [
    "//包含抽象方法的类必须被定义为抽象类，抽象类不能被实例化。\n",
    "abstract class Animal{\n",
    "    \n",
    "    //声明属性\n",
    "    public static String home = \"Earth\";\n",
    "    public String name; //初始化为null\n",
    "   \n",
    "    \n",
    "    //构造方法\n",
    "    public Animal(String name){\n",
    "        this.name = name;\n",
    "    }\n",
    "    \n",
    "    abstract public void call(); //抽象方法只定义签名\n",
    "    \n",
    "}\n",
    "\n",
    "//定义一个接口，接口也将被编译成一个.class文件\n",
    "interface Runnable{\n",
    "    public static String place = \"road\";\n",
    "    String getName(); \n",
    "    \n",
    "    default public void run(){\n",
    "        System.out.println(getName() + \" is running in the \" + place + \" ...\");\n",
    "    }\n",
    "    \n",
    "}\n",
    "\n",
    "\n",
    "//继承自抽象类和接口\n",
    "class Dog extends Animal implements Runnable{\n",
    "    \n",
    "    //构造方法\n",
    "    public Dog(String name){\n",
    "        super(name); //调用父类的构造方法\n",
    "    }\n",
    "    \n",
    "    \n",
    "    //实现继承的父类中的抽象方法\n",
    "    @Override \n",
    "    public void call(){\n",
    "        System.out.println(\"Bowwow,Bowwow,Bowwow...\");\n",
    "    }\n",
    "    \n",
    "    //实现继承的接口中的抽象方法\n",
    "    public String getName(){\n",
    "        return this.name;\n",
    "    }\n",
    "}\n",
    "\n",
    "\n",
    "Dog snoopy = new Dog(\"snoopy\");\n",
    "System.out.println(snoopy.place); //调用继承自接口的静态属性\n",
    "snoopy.run(); //调用继承自接口的default方法;\n",
    "\n",
    "//判断继承关系\n",
    "System.out.println(snoopy instanceof Dog);\n",
    "System.out.println(snoopy instanceof Animal);\n",
    "System.out.println(snoopy instanceof Object);\n",
    "System.out.println(snoopy instanceof Runnable);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十四，反射"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "通常我们通过类来创建实例，但反射机制让我们能够通过实例来获取类的信息。\n",
    "\n",
    "包括类的名字，类的属性和方法签名，类的继承关系等等。\n",
    "\n",
    "当加载进一个class类文件时，JVM会创建一个Class类型的实例来保存类的信息。\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，获取Class类型实例**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:15+0000",
     "start_time": "2019-09-15T12:15:34.667Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "class java.lang.String"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//通过类名直接获取Class实例\n",
    "Class cls = String.class;\n",
    "cls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:15+0000",
     "start_time": "2019-09-15T12:15:45.292Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "class java.lang.String"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//通过getClass方法获取Class实例\n",
    "String s = \"Hello world\";\n",
    "Class cls = s.getClass();\n",
    "cls"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:16+0000",
     "start_time": "2019-09-15T12:16:32.136Z"
    }
   },
   "outputs": [],
   "source": [
    "//通过Class.forName静态方法获取Class实例\n",
    "Class cls = Class.forName(\"java.lang.String\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:18+0000",
     "start_time": "2019-09-15T12:18:01.555Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "true\n",
      "true\n"
     ]
    }
   ],
   "source": [
    "//以上几种方式等价\n",
    "System.out.println(String.class == \"Hello World\".getClass());\n",
    "System.out.println(String.class == Class.forName(\"java.lang.String\"));"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2，访问属性**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Field getField(name)：根据字段名获取某个public的field（包括父类）\n",
    "* Field getDeclaredField(name)：根据字段名获取当前类的某个field（不包括父类）\n",
    "* Field[] getFields()：获取所有public的field（包括父类）\n",
    "* Field[] getDeclaredFields()：获取当前类的所有field（不包括父类）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:29+0000",
     "start_time": "2019-09-15T12:29:40.016Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "private final byte[] java.lang.String.value\n",
      "private final byte java.lang.String.coder\n",
      "private int java.lang.String.hash\n",
      "private static final long java.lang.String.serialVersionUID\n",
      "static final boolean java.lang.String.COMPACT_STRINGS\n",
      "private static final java.io.ObjectStreamField[] java.lang.String.serialPersistentFields\n",
      "public static final java.util.Comparator java.lang.String.CASE_INSENSITIVE_ORDER\n",
      "static final byte java.lang.String.LATIN1\n",
      "static final byte java.lang.String.UTF16\n"
     ]
    }
   ],
   "source": [
    "import java.lang.reflect.Field;\n",
    "\n",
    "String s = \"Hello world\";\n",
    "Class cls = s.getClass();\n",
    "for (Field f: cls.getDeclaredFields()){\n",
    "    System.out.println(f);\n",
    "}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:40+0000",
     "start_time": "2019-09-15T12:40:53.881Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hash\n",
      "int\n",
      "\n",
      "false\n",
      "false\n",
      "false\n",
      "true\n",
      "false\n"
     ]
    }
   ],
   "source": [
    "//获取单个属性信息\n",
    "\n",
    "import java.lang.reflect.Field;\n",
    "import java.lang.reflect.Modifier;\n",
    "\n",
    "Field f = String.class.getDeclaredField(\"hash\");\n",
    "\n",
    "System.out.println(f.getName());\n",
    "System.out.println(f.getType()+\"\\n\");\n",
    "\n",
    "\n",
    "int m = f.getModifiers();\n",
    "System.out.println(Modifier.isFinal(m)); \n",
    "System.out.println(Modifier.isPublic(m)); \n",
    "System.out.println(Modifier.isProtected(m)); \n",
    "System.out.println(Modifier.isPrivate(m)); \n",
    "System.out.println(Modifier.isStatic(m)); \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:51+0000",
     "start_time": "2019-09-15T12:51:33.292Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "snoopy\n",
      "kitty\n"
     ]
    }
   ],
   "source": [
    "//获取实例某个属性的取值\n",
    "\n",
    "class Animal{\n",
    "\n",
    "    public String name; \n",
    "   \n",
    "    //构造方法\n",
    "    public Animal(String name){\n",
    "        this.name = name;\n",
    "    }\n",
    "}\n",
    "\n",
    "Animal snoopy = new Animal(\"snoopy\");\n",
    "Class cls = snoopy.getClass();\n",
    "Field f = cls.getDeclaredField(\"name\");\n",
    "\n",
    "//允许访问私有字段\n",
    "f.setAccessible(true);\n",
    "\n",
    "//获取属性值\n",
    "Object value = f.get(snoopy);\n",
    "System.out.println(value);\n",
    "\n",
    "//修改属性值\n",
    "f.set(snoopy,\"kitty\");\n",
    "System.out.println(snoopy.name);\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:41+0000",
     "start_time": "2019-09-15T12:41:28.922Z"
    }
   },
   "source": [
    "**3，调用方法**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "* Method getMethod(name, Class...)：获取某个public的Method（包括父类）\n",
    "* Method getDeclaredMethod(name, Class...)：获取当前类的某个Method（不包括父类）\n",
    "* Method[] getMethods()：获取所有public的Method（包括父类）\n",
    "* Method[] getDeclaredMethods()：获取当前类的所有Method（不包括父类）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:55+0000",
     "start_time": "2019-09-15T12:55:11.491Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Hello \n"
     ]
    }
   ],
   "source": [
    "import java.lang.reflect.Method;\n",
    "public class Main {\n",
    "    public static void main(String[] args) throws Exception {\n",
    "        // String对象:\n",
    "        String s = \"Hello world\";\n",
    "        // 获取String substring(int,int)方法，参数为int,int:\n",
    "        Method m = String.class.getMethod(\"substring\",int.class,int.class);\n",
    "        // 在s对象上调用该方法并获取结果:\n",
    "        String r = (String) m.invoke(s, 0, 6);\n",
    "        // 打印调用结果:\n",
    "        System.out.println(r);\n",
    "    }\n",
    "}\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**4，调用构造方法**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:57+0000",
     "start_time": "2019-09-15T12:57:56.907Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": []
     },
     "execution_count": 30,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "//调用无参数的构造方法\n",
    "String p = String.class.newInstance();\n",
    "p"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T12:58+0000",
     "start_time": "2019-09-15T12:58:40.851Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "123\n",
      "456\n"
     ]
    }
   ],
   "source": [
    "//调用待参数的构造方法\n",
    "import java.lang.reflect.Constructor;\n",
    "\n",
    "public class Main {\n",
    "    public static void main(String[] args) throws Exception {\n",
    "        // 获取构造方法Integer(int):\n",
    "        Constructor cons1 = Integer.class.getConstructor(int.class);\n",
    "        // 调用构造方法:\n",
    "        Integer n1 = (Integer) cons1.newInstance(123);\n",
    "        System.out.println(n1);\n",
    "\n",
    "        // 获取构造方法Integer(String)\n",
    "        Constructor cons2 = Integer.class.getConstructor(String.class);\n",
    "        Integer n2 = (Integer) cons2.newInstance(\"456\");\n",
    "        System.out.println(n2);\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**5，获取继承关系**"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Class getSuperclass()：获取父类类型；\n",
    "\n",
    "Class[] getInterfaces()：获取当前类实现的所有接口。\n",
    "\n",
    "通过Class对象的isAssignableFrom()方法可以判断一个向上转型是否可以实现。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T13:00+0000",
     "start_time": "2019-09-15T13:00:54.537Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "class java.lang.Number\n",
      "class java.lang.Object\n",
      "null\n"
     ]
    }
   ],
   "source": [
    "//获取继承的父类\n",
    "public class Main {\n",
    "    public static void main(String[] args) throws Exception {\n",
    "        Class i = Integer.class;\n",
    "        Class n = i.getSuperclass();\n",
    "        System.out.println(n);\n",
    "        Class o = n.getSuperclass();\n",
    "        System.out.println(o);\n",
    "        System.out.println(o.getSuperclass());\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T13:02+0000",
     "start_time": "2019-09-15T13:02:19.294Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "interface java.lang.Comparable\n",
      "interface java.lang.constant.Constable\n",
      "interface java.lang.constant.ConstantDesc\n"
     ]
    }
   ],
   "source": [
    "//获取继承的接口\n",
    "import java.lang.reflect.Method;\n",
    "public class Main {\n",
    "    public static void main(String[] args) throws Exception {\n",
    "        Class s = Integer.class;\n",
    "        Class[] is = s.getInterfaces();\n",
    "        for (Class i : is) {\n",
    "            System.out.println(i);\n",
    "        }\n",
    "    }\n",
    "}\n",
    "\n",
    "Main.main(new String[]{})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T13:06+0000",
     "start_time": "2019-09-15T13:06:12.662Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "false"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "// Integer i = ?\n",
    "Integer.class.isAssignableFrom(Integer.class); // true，因为Integer可以赋值给Integer\n",
    "// Number n = ?\n",
    "Number.class.isAssignableFrom(Integer.class); // true，因为Integer可以赋值给Number\n",
    "// Object o = ?\n",
    "Object.class.isAssignableFrom(Integer.class); // true，因为Integer可以赋值给Object\n",
    "// Integer i = ?\n",
    "Integer.class.isAssignableFrom(Number.class); // false，因为Number不能赋值给Integer"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十五，泛型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "泛型就是编写模板代码来适应任意类型。Java的容器类中大量使用了泛型。\n",
    "\n",
    "泛型的好处是使用时不必对类型进行强制转换，它通过编译器对类型进行检查。\n",
    "    \n",
    "Java中泛型的实现是使用的擦拭法，编译器编译包含泛型的类时将泛型换成Object类型，\n",
    "    \n",
    "编译器泛型实例化的代码时根据泛型的具体类型进行安全转型，而JVM虚拟机对泛型一无所知。\n",
    "    \n",
    "因此泛型的类型不能是int,float,double等基本类型，并且不能够获取泛型的反射。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T13:45+0000",
     "start_time": "2019-09-15T13:45:06.436Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.0\n"
     ]
    }
   ],
   "source": [
    "//尖括号<>表示泛型\n",
    "public class Pair<T> {\n",
    "    private T first;\n",
    "    private T last;\n",
    "    public Pair(T first, T last) {\n",
    "        this.first = first;\n",
    "        this.last = last;\n",
    "    }\n",
    "    public T getFirst() {\n",
    "        return first;\n",
    "    }\n",
    "    public T getLast() {\n",
    "        return last;\n",
    "    }\n",
    "}\n",
    "\n",
    "Pair<Double> p =  new Pair<Double>(1.0,2.0);\n",
    "System.out.println(p.getFirst());"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-09-15T13:48+0000",
     "start_time": "2019-09-15T13:48:48.733Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "abc\n"
     ]
    }
   ],
   "source": [
    "//可以包括多个不同类型\n",
    "public class Pair<T,K> {\n",
    "    private T first;\n",
    "    private K last;\n",
    "    public Pair(T first, K last) {\n",
    "        this.first = first;\n",
    "        this.last = last;\n",
    "    }\n",
    "    public T getFirst() {\n",
    "        return first;\n",
    "    }\n",
    "    public K getLast() {\n",
    "        return last;\n",
    "    }\n",
    "}\n",
    "\n",
    "Pair<String,Double> p =  new Pair<String,Double>(\"abc\",2.0);\n",
    "System.out.println(p.getFirst());"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十六，注解"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java中的注解是放在Java源码的类、方法、属性、参数前的一种特殊\"注释\",以@开头。\n",
    "\n",
    "注解可以看成用作标注的一种\"元数据\"。\n",
    "\n",
    "Java中有3中不同的注解：\n",
    "\n",
    "* SOURCE类型的注解由编译器使用，在编译期被丢掉了，如@Override；\n",
    "* CLASS类型的注解仅保存在class文件中，这类注解只被一些底层库使用，它们不会被加载进JVM；\n",
    "* RUNTIME类型的注解会被加载进JVM，并且在运行期可以被程序读取。\n",
    "\n",
    "Java语言使用@interface语法来定义注解（Annotation），定义注解一般需要用到元注解。\n",
    "\n",
    "元注解（meta annotation）就是可以用来修饰其它注解的注解。\n",
    "\n",
    "Java标准库已经定义了一些元注解，我们只需要使用元注解，通常不需要自己去编写元注解。\n",
    "\n",
    "注解定义后也是一种class，所有的注解都继承自java.lang.annotation.Annotation，因此，读取注解，需要使用反射API。\n",
    "\n",
    "RUNTIME类型的注解如何使用，完全由程序自己决定。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十七，Scala和Java的对比"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Java发明于1995年，Scala发明于2003年。\n",
    "\n",
    "Scala和Java都是JVM语言，两者的源码都将编译成.class字节码在JVM虚拟机上执行。\n",
    "\n",
    "因此Scala和Java可以无缝混编。\n",
    "\n",
    "Scala在Java基础上做了重大的改进，使其兼备静态语言和脚本语言的特色。\n",
    "\n",
    "下面列举一些比较显著的差异。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**1，Scala比Java更加简洁**\n",
    "\n",
    "Java 中打印用 System.out.println, 而Scala用 println，类似Python。\n",
    "\n",
    "Java 许多地方语句中的分号”;“不能省略, 而Scala可以省略，类似Python。\n",
    "\n",
    "Java 声明变量时，先声明类型，再声明变量名，而Scala则先变量名，必要时用冒号说明类型，类似Python。\n",
    "\n",
    "Java 定义方法无需关键字，Scala 定义方法用关键字 def，可读性更强，类似Python. \n",
    "\n",
    "Scala支持for推导式,类似Python.\n",
    "\n",
    "Scala 支持类型推断，Java 在后面的版本才增加了 var 关键字来支持类型推断。\n",
    "\n",
    "Scala 支持隐式类型转换和隐式参数。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**2, Scala比Java更加灵活**\n",
    "\n",
    "Java必须先编译后才能执行，Scala解释器可以直接运行Scala脚本。\n",
    "\n",
    "Java编程风格统一为面向对象，Scala支持面向对象和函数式编程多种风格\n",
    "\n",
    "Java中的多分支用switch, Scala使用match模式匹配实现多分支。\n",
    "\n",
    "Java中的类支持静态属性和静态方法，Scala用伴生对象和伴生方法概念将静态属性和方法与实例属性和方法分离。\n",
    "\n",
    "Java的循环中支持break和continue关键字，Scala的循环中不支持。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**3，常用标点符号差异**\n",
    "\n",
    "Java中导入全部对象用星号作为通配符，Scala中用下划线作为通配符。\n",
    "\n",
    "Java中用方括号来取索引，Scala中用圆括号来取索引。\n",
    "\n",
    "Java中用尖括号来表示泛型，Scala中用方括号来表示泛型。\n",
    "\n",
    "Java中的数组用花括号来表示，Scala中只能用工厂方法。\n",
    "\n",
    "Java中可以用冒号来书写for each语句,Scala中用<- 来书写。\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 二十八，Java和C++的对比"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "C++发明于1983年，而Java发明于1995年。\n",
    "\n",
    "C++代码直接编译成机器码运行在裸机上，而Java代码编译成字节码运行在虚拟机上。\n",
    "\n",
    "C++编译的最终结果是一个程序生成一个exe文件。Java编译结果是一个程序中有多少类就生成多少个与类名相同的class文件。\n",
    "\n",
    "Java的语法大量借鉴了C++，但和C++相比，Java是一门纯面向对象的语言，风格更加简洁统一。\n",
    "\n",
    "下面列举一些两者语法上的差异。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1，C++ 导入package使用 #include， 而 Java使用 import 关键字 。\n",
    "\n",
    "2，C++ 支持指针直接操控内存，而 Java 抛弃了令人困惑的指针功能。\n",
    "\n",
    "3，C++ 使用析构函数回收垃圾，java自动回收（GC算法）。\n",
    "\n",
    "4，C++ 支持直接多继承性，Java用接口来实现多继承性。\n",
    "\n",
    "5，C++ 中可以在类的外部可以定义函数，而Java不允许在类和接口外面直接定义方法。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Java",
   "language": "java",
   "name": "java"
  },
  "language_info": {
   "codemirror_mode": "java",
   "file_extension": ".jshell",
   "mimetype": "text/x-java-source",
   "name": "Java",
   "pygments_lexer": "java",
   "version": "12.0.2+10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
